#include<assert.h>
#include"residue_math.h"
#include <cstdlib>
#include<iostream>

ZZ pow(const ZZ & base, long p)
{
    return power(base, p);
}

ZZ pow(const ZZ & base, const ZZ & p, const ZZ & mod)
{
    return PowerMod(base, p, mod);
}

ZZ gen_prime(long l)
{
	return GenPrime_ZZ(l);
}

ZZ gen_strong_prime(long l)
{
	ZZ p_1 = GenGermainPrime_ZZ(l-1);
	ZZ p = 2*p_1 +1;
	return p;
}
ZZ rand_mod(const ZZ & mod)
{
	return RandomBnd(mod);
}


bool inv(const ZZ & n, const ZZ & mod, ZZ &res)
{
	if (GCD(n,mod) != 1) return false;
	else
	{
		res = InvMod(n,mod);
		return true;
	}
}


ZZ gcd(const ZZ & a, const  ZZ & b)
{
        return GCD(a, b);
}

int calc_Jacobi(const ZZ & a, const ZZ & n)
{
	return Jacobi(a,n);
}

ZZ find_Jacobi_eq(int t, const  ZZ & mod)
{
	ZZ x = rand_mod(mod);
	while (calc_Jacobi(x, mod) != t)
	{
		x = rand_mod(mod);
	}
	return x;

}

